﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace PromoServer.Library.Entities
{
    public class Schedule : INotifyPropertyChanged, IDataErrorInfo
    {
        // Declare the property changed event 
        public event PropertyChangedEventHandler PropertyChanged;

        private int _scheduleID;
        public int ScheduleID 
        {
            get
            {
                return _scheduleID;
            }
            set
            {
                _scheduleID = value;
            }
        }

        public string Name { get; set; }

        private bool _monday;
        public bool Monday 
        {
            get
            {
                return _monday;
            }
            set 
            {
                _monday = value; 
                OnPropertyChanged("ScheduleSummary"); 
            } 
        }

        private bool _tuesday;
        public bool Tuesday
        {
            get
            {
                return _tuesday;
            }
            set
            {
                _tuesday = value;
                OnPropertyChanged("ScheduleSummary");
            }
        }

        private bool _wednesday;
        public bool Wednesday
        {
            get
            {
                return _wednesday;
            }
            set
            {
                _wednesday = value;
                OnPropertyChanged("ScheduleSummary");
            }
        }

        private bool _thursday;
        public bool Thursday
        {
            get
            {
                return _thursday;
            }
            set
            {
                _thursday = value;
                OnPropertyChanged("ScheduleSummary");
            }
        }

        private bool _friday;
        public bool Friday
        {
            get
            {
                return _friday;
            }
            set
            {
                _friday = value;
                OnPropertyChanged("ScheduleSummary");
            }
        }

        private bool _saturday;
        public bool Saturday
        {
            get
            {
                return _saturday;
            }
            set
            {
                _saturday = value;
                OnPropertyChanged("ScheduleSummary");
            }
        }

        private bool _sunday;
        public bool Sunday
        {
            get
            {
                return _sunday;
            }
            set
            {
                _sunday = value;
                OnPropertyChanged("ScheduleSummary");
            }
        }

        private int _startDate;
        public DateTime StartDate 
        {
            get
            {
                return Convert.ToDateTime(_startDate.ToString().Substring(4, 2) + "/" + _startDate.ToString().Substring(6, 2) + "/" + _startDate.ToString().Substring(0, 4));
            }
            set
            {
                string strStartDateNumber = value.Year.ToString() + value.Month.ToString().PadLeft(2, '0') + value.Day.ToString().PadLeft(2, '0');
                _startDate = Convert.ToInt32(strStartDateNumber);
                OnPropertyChanged("ScheduleSummary");
            }
        }
        public int StartDateAsNumber
        {
            get
            {
                return _startDate;
            }
        }

        private int _endDate;
        public DateTime EndDate 
        {
            get
            {
                return Convert.ToDateTime(_endDate.ToString().Substring(4, 2) + "/" + _endDate.ToString().Substring(6, 2) + "/" + _endDate.ToString().Substring(0, 4));
            }
            set
            {
                string strEndDateNumber = value.Year.ToString() + value.Month.ToString().PadLeft(2, '0') + value.Day.ToString().PadLeft(2, '0');
                _endDate = Convert.ToInt32(strEndDateNumber);
                OnPropertyChanged("ScheduleSummary");
            }
        }
        public int EndDateAsNumber
        {
            get
            {
                return _endDate;
            }
        }

        public string StartTime 
        {
            get
            {
                return _startHour + _startMinute;
            }
        }
        public string EndTime
        {
            get
            {
                return _endHour + _endMinute;
            }
        }

        private string _startHour;
        public string StartHour
        {
            set
            {
                _startHour = value;
                OnPropertyChanged("ScheduleSummary");
            }
            get
            {
                DateTime tmpDTResult;
                string tmpDT= "01/01/2013 " + _startHour + ":00:00";
                DateTime.TryParse(tmpDT, out tmpDTResult);
                if (tmpDTResult.Ticks != 0)
                {
                    // Convert time to 12 hour and return hour
                    DateTime tmpDateTime = new DateTime(2013, 1, 1, Convert.ToInt32(_startHour), 0, 0);
                    string tmpDateTimeAMPM = tmpDateTime.ToString("hh:mm:ss tt");
                    return tmpDateTimeAMPM.Substring(0, 2);
                }
                else return _startHour;
            }
        }

        private string _startMinute;
        public string StartMinute
        {
            set
            {
                // Set minute
                _startMinute = value.PadLeft(2, '0');
                OnPropertyChanged("ScheduleSummary");
            }
            get
            {
                DateTime tmpDTResult;
                string tmpDT = "01/01/2013 " + _startHour + ":" + _startMinute + ":00";
                DateTime.TryParse(tmpDT, out tmpDTResult);
                if (tmpDTResult.Ticks != 0)
                {
                    // Convert time to 12 hour and return minute
                    DateTime tmpDateTime = new DateTime(2013, 1, 1, Convert.ToInt32(_startHour), Convert.ToInt32(_startMinute), 0);
                    string tmpDateTimeAMPM = tmpDateTime.ToString("hh:mm:ss tt");
                    return tmpDateTimeAMPM.Substring(3, 2);
                }
                else return _startMinute;
            }
        }

        private string _endHour;
        public string EndHour
        {
            set
            {
                _endHour = value;
                OnPropertyChanged("ScheduleSummary");
            }
            get
            {
                DateTime tmpDTResult;
                string tmpDT = "01/01/2013 " + _endHour + ":00:00";
                DateTime.TryParse(tmpDT, out tmpDTResult);
                if (tmpDTResult.Ticks != 0)
                {
                    // Convert time to 12 hour and return hour
                    DateTime tmpDateTime = new DateTime(2013, 1, 1, Convert.ToInt32(_endHour), 0, 0);
                    string tmpDateTimeAMPM = tmpDateTime.ToString("hh:mm:ss tt");
                    return tmpDateTimeAMPM.Substring(0, 2);
                }
                else return _endHour;
            }
        }

        private string _endMinute;
        public string EndMinute
        {
            set
            {
                // Set minute
                _endMinute = value.PadLeft(2, '0');
                OnPropertyChanged("ScheduleSummary");
            }
            get
            {
                DateTime tmpDTResult;
                string tmpDT = "01/01/2013 " + _endHour + ":" + _endMinute + ":00";
                DateTime.TryParse(tmpDT, out tmpDTResult);
                if (tmpDTResult.Ticks != 0)
                {
                    // Convert time to 12 hour and return minute
                    DateTime tmpDateTime = new DateTime(2013, 1, 1, Convert.ToInt32(_endHour), Convert.ToInt32(_endMinute), 0);
                    string tmpDateTimeAMPM = tmpDateTime.ToString("hh:mm:ss tt");
                    return tmpDateTimeAMPM.Substring(3, 2);
                }
                else return _endMinute;
            }
        }

        private string _startPeriod;
        public string StartPeriod 
        {
            get
            {
                return _startPeriod;
            }
            set
            {
                _startPeriod = value;
                OnPropertyChanged("ScheduleSummary");
            }
        }

        private string _endPeriod;
        public string EndPeriod
        {
            get
            {
                return _endPeriod;
            }
            set
            {
                _endPeriod = value;
                OnPropertyChanged("ScheduleSummary");
            }
        }

        public ObservableCollection<string> ValidPeriods
        {
            get
            {
                List<string> validPeriods = new List<string>();
                validPeriods.Add("AM");
                validPeriods.Add("PM");
                return new ObservableCollection<string>(validPeriods);
            }
        }

        public string ScheduleSummary
        {
            get
            {
                string summary = string.Empty;

                // Set frequency
                if (!Monday && !Tuesday && !Wednesday && !Thursday && !Friday && !Saturday && !Sunday)
                {
                    summary = "Runs never";
                    return summary;
                }
                else
                {
                    summary = "Runs every";

                    if (Monday)
                        summary += " Monday,";

                    if (Tuesday)
                        summary += " Tuesday,";

                    if (Wednesday)
                        summary += " Wednesday,";

                    if (Thursday)
                        summary += " Thursday,";

                    if (Friday)
                        summary += " Friday,";

                    if (Saturday)
                        summary += " Saturday,";

                    if (Sunday)
                        summary += " Sunday,";

                    summary = summary.Substring(0, summary.Length - 1);
                }
                
                // Set daily frequency
                summary += " from " + StartHour + ":" + StartMinute + " " + StartPeriod;
                summary += " until " + EndHour + ":" + EndMinute + " " + EndPeriod;
                summary += ".";

                // Set duration
                summary += " Schedule will be used starting " + StartDate.ToShortDateString();
                summary += " and ending " + EndDate.ToShortDateString();
                summary += ".";

                return summary;
            }
        }
        
        public Schedule(string name)
        {
            // Default Instance
            _scheduleID = 0;
            Name = name;
            _monday = true;
            _tuesday = true;
            _wednesday = true;
            _thursday = true;
            _friday = true;
            _saturday = true;
            _sunday = true;
            _startDate = Convert.ToInt32(DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString().PadLeft(2, '0') + DateTime.Now.Day.ToString().PadLeft(2, '0'));
            _endDate = 99991231;
            _startHour = "00";
            _startMinute = "00";
            _startPeriod = "AM";
            _endHour = "23";
            _endMinute = "59";
            _endPeriod = "PM";
        }

        public Schedule(int scheduleID, string name, bool monday, bool tuesday, bool wednesday, bool thursday, bool friday, bool saturday, bool sunday, int startDate, int endDate, int startTime, int endTime)
        {
            // Saved Instance
            _scheduleID = scheduleID;
            Name = name;
            _monday = monday;
            _tuesday = tuesday;
            _wednesday = wednesday;
            _thursday = thursday;
            _friday = friday;
            _saturday = saturday;
            _sunday = sunday;
            _startDate = startDate;
            _endDate = endDate;

            _startHour = startTime.ToString().PadLeft(4, '0').Substring(0, 2);
            _startMinute = startTime.ToString().PadLeft(4, '0').Substring(2, 2);

            _endHour = endTime.ToString().PadLeft(4, '0').Substring(0, 2);
            _endMinute = endTime.ToString().PadLeft(4, '0').Substring(2, 2);

            if (Convert.ToInt32(_startHour) > 12)
                _startPeriod = "PM";
            else
                _startPeriod = "AM";

            if (Convert.ToInt32(_endHour) > 12)
                _endPeriod = "PM";
            else
                _endPeriod = "AM";
        }

        #region INotifyPropertyChanged Members
        // Create the OnPropertyChanged method to raise the event 
        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }
        #endregion

        #region IDataErrorInfo Members

        public string Error
        {
            get { return String.Empty; }
        }

        public string this[string columnName]
        {
            get
            {
                String errorMessage = String.Empty;
                switch (columnName)
                {
                    case "StartHour":
                        int tryStartHourParseReturn;
                        Int32.TryParse(StartHour, out tryStartHourParseReturn);
                        if (String.IsNullOrEmpty(StartHour) || Convert.ToInt32(StartHour) < 1 || Convert.ToInt32(StartHour) > 12 || tryStartHourParseReturn == 0)
                        {
                            errorMessage = "The hour value must be a number between 1 and 12";
                        }
                        else
                        {
                            // Convert time to 24 hour and set hour
                            DateTime tmpDateTime = new DateTime();
                            tmpDateTime = Convert.ToDateTime("01/01/2013 " + _startHour.ToString().PadLeft(2, '0') + ":00:00 " + _startPeriod);
                            string tmpDateTimeAMPM = tmpDateTime.ToString("HH:mm:ss tt");
                            _startHour = tmpDateTimeAMPM.Substring(0, 2).PadLeft(2, '0');
                        }
                        break;
                    case "EndHour":
                        int tryEndHourParseReturn;
                        Int32.TryParse(EndHour, out tryEndHourParseReturn);
                        if (String.IsNullOrEmpty(EndHour) || Convert.ToInt32(EndHour) < 1 || Convert.ToInt32(EndHour) > 12 || tryEndHourParseReturn == 0)
                        {
                            errorMessage = "The hour value must be a number between 1 and 12";
                        }
                        else
                        {
                            // Convert time to 24 hour and set hour
                            DateTime tmpDateTime = new DateTime();
                            tmpDateTime = Convert.ToDateTime("01/01/2013 " + _endHour.ToString().PadLeft(2, '0') + ":00:00 " + _endPeriod);
                            string tmpDateTimeAMPM = tmpDateTime.ToString("HH:mm:ss tt");
                            _endHour = tmpDateTimeAMPM.Substring(0, 2).PadLeft(2, '0');
                        }
                        break;
                    case "StartMinute":
                        if (Convert.ToInt32(StartMinute) > 59 || Convert.ToInt32(StartMinute) < 0)
                        {
                            errorMessage = "The minute value must be a number between 0 and 59";
                        }
                        break;
                    case "EndMinute":
                        if (Convert.ToInt32(EndMinute) > 59 || Convert.ToInt32(EndMinute) < 0)
                        {
                            errorMessage = "The minute value must be a number between 0 and 59";
                        }
                        break;
                }
                return errorMessage;
            }
        }

        #endregion
    }
}
